import { POST_CONTENT_TYPE_OBJ, POST_OTHER_STATE_LIST } from '@/lib/constant';
import { getCover } from '@/lib/tool';
import { type ChangeEvent, useContext } from 'react';
import type {
  ISection,
  IUploadPostCover,
  IUploadPostCoverBody,
  IUploadPostNewFile,
  IUploadPostNewFileBody,
} from '@/interfaces';
import type { TBody, TMetadata } from '@/types';
import useToast from '@/hooks/useToast';
import { useMutation } from '@tanstack/react-query';
import { uploadPostCover, uploadPostNewFile } from '@/services/api';
import { EditPostContext } from '@/contexts/edit';
import { useTranslations } from 'use-intl';
import {
  postContentTypeTranslator,
  postOtherStateTranslator,
} from '@/lib/translator';

export default function Content(
  this: any,
  {
    id,
    isEdit,
    metadata,
    sections,
  }: {
    id?: number;
    isEdit?: boolean;
    metadata: TMetadata;
    sections: ISection[];
  },
) {
  const { show } = useToast();
  const { form, setForm, onClickSave } = useContext(EditPostContext)!;
  const t = useTranslations('PostEditPage');

  const uploadPostCoverMutation = useMutation(
    async (variables: TBody<IUploadPostCoverBody>) => {
      return (await uploadPostCover(variables)) as IUploadPostCover;
    },
  );
  const uploadPostNewCoverMutation = useMutation(
    async (variables: TBody<IUploadPostNewFileBody>) => {
      return (await uploadPostNewFile(variables)) as IUploadPostNewFile;
    },
  );

  async function onClickUploadCover() {
    try {
      const file = form.uploadCoverFile;
      if (!file) {
        show({
          type: 'DANGER',
          message: t('noFileSelected'),
        });
        return;
      }

      let result;
      if (isEdit) {
        result = await uploadPostCoverMutation.mutateAsync({
          id: id,
          data: { file },
        });
      } else {
        result = await uploadPostNewCoverMutation.mutateAsync({
          data: { file },
        });
      }

      if (form.uploadCoverObjectUrl) {
        URL.revokeObjectURL(form.uploadCoverObjectUrl);
      }

      setForm({
        ...form,
        uploadCoverObjectUrl: '',
        uploadCoverFile: '',
        uploadCover: '',
        cover: result.urls.default,
      });
      show({
        type: 'SUCCESS',
        message: t('uploadCompleted'),
      });
    } catch (e) {
      if (isEdit) {
        uploadPostCoverMutation.reset();
      } else {
        uploadPostNewCoverMutation.reset();
      }

      setForm({
        ...form,
        uploadCoverObjectUrl: '',
        uploadCoverFile: '',
        uploadCover: '',
      });

      show({
        type: 'DANGER',
        message: e,
      });
    }
  }

  function onChange(
    e: ChangeEvent<HTMLInputElement | HTMLTextAreaElement | HTMLSelectElement>,
  ) {
    const name = e.target.name;
    const value = e.target.value;

    if (name === 'uploadCover') {
      if (form.uploadCoverObjectUrl) {
        URL.revokeObjectURL(form.uploadCoverObjectUrl);
      }

      const file = (e.target as any).files[0];
      const objectUrl = URL.createObjectURL(file);
      setForm({
        ...form,
        uploadCover: value,
        uploadCoverFile: file,
        uploadCoverObjectUrl: objectUrl,
      });
    } else if (name === 'customTags') {
      setForm({
        ...form,
        customTags: value.replaceAll('，', ',').split(','),
      });
    } else if (name === 'otherStates') {
      let otherStates: any[];
      if (form.otherStates.find((item) => item === value)) {
        otherStates = form.otherStates.filter((item) => item !== value);
      } else {
        otherStates = [...form.otherStates, value];
      }

      setForm({
        ...form,
        otherStates,
      });
    } else if (name === 'allow') {
      setForm({
        ...form,
        allow: value.replaceAll('，', ',').split(','),
      });
    } else if (name === 'block') {
      setForm({
        ...form,
        block: value.replaceAll('，', ',').split(','),
      });
    } else {
      setForm({
        ...form,
        [name]: value,
      });
    }
  }

  return (
    <div className="row">
      <div className="col">
        <form onSubmit={onClickSave} className="vstack gap-4">
          <div className="card">
            <div className="card-body">
              <div className="vstack gap-4">
                <div>
                  <select
                    name="contentType"
                    value={form.contentType}
                    onChange={onChange}
                    className="form-select"
                    placeholder={t('contentRequired')}
                  >
                    <option value="" disabled>
                      {t('contentTypeRequired')}
                    </option>
                    {Object.entries(POST_CONTENT_TYPE_OBJ).map((value) => {
                      return (
                        <option key={value[0]} value={value[0]}>
                          {t(postContentTypeTranslator(value[0]))}
                        </option>
                      );
                    })}
                  </select>

                  {form.contentType === 'LINK' && (
                    <div className="form-text">
                      <i className="bi bi-info-circle me-2"></i>
                      {t('enterLinkInEditor')}
                    </div>
                  )}

                  {form.contentType === 'NONE' && (
                    <div className="form-text">
                      <i className="bi bi-info-circle me-2"></i>
                      {t('clearAllContentInEditor')}
                    </div>
                  )}
                </div>

                <select
                  name="sectionId"
                  value={form.sectionId}
                  onChange={onChange}
                  className="form-select"
                  placeholder={t('contentRequired')}
                >
                  <option value="" disabled>
                    {t('contentRequired')}
                  </option>
                  {sections.map((item) => {
                    return (
                      <option key={item.id} value={item.id}>
                        {item.name}
                      </option>
                    );
                  })}
                </select>

                <div className="form-control">
                  {POST_OTHER_STATE_LIST.map((key: any, index) => {
                    return (
                      <div key={key} className="form-check form-check-inline">
                        <input
                          id={`yw-post-otherStates-${key}-${index}`}
                          aria-label="otherStates"
                          name="otherStates"
                          onChange={onChange}
                          className="form-check-input"
                          type="checkbox"
                          value={key}
                          checked={form.otherStates.includes(key)}
                          disabled={
                            ((form.otherStates || []).length > 0 &&
                              !form.otherStates?.includes('DEFAULT') &&
                              key === 'DEFAULT') ||
                            (form.otherStates?.includes('DEFAULT') &&
                              key !== 'DEFAULT')
                          }
                        />
                        <label
                          className="form-check-label user-select-none"
                          htmlFor={`yw-post-otherStates-${key}-${index}`}
                        >
                          {t(postOtherStateTranslator(key))}
                        </label>
                      </div>
                    );
                  })}
                </div>

                {form.otherStates.includes('ALLOW') && (
                  <textarea
                    rows={1}
                    className="form-control"
                    name="allow"
                    value={form.allow}
                    onChange={onChange}
                    placeholder={t('whitelistUserIds')}
                  />
                )}

                {form.otherStates.includes('BLOCK') && (
                  <textarea
                    rows={1}
                    className="form-control"
                    name="block"
                    value={form.block}
                    onChange={onChange}
                    placeholder={t('blacklistUserUserIds')}
                  />
                )}
              </div>
            </div>
          </div>
          <div className="card">
            <div className="card-body">
              <div className="vstack gap-4">
                <textarea
                  name="overview"
                  value={form.overview}
                  onChange={onChange}
                  className="form-control"
                  rows={3}
                  placeholder={t('summaryRequired')}
                />

                <input
                  name="customTags"
                  value={form.customTags.join(',')}
                  onChange={onChange}
                  className="form-control"
                  placeholder={t('tagsRequired')}
                />

                <textarea
                  name="statement"
                  value={form.statement}
                  onChange={onChange}
                  className="form-control"
                  rows={1}
                  placeholder={t('disclaimerRequired')}
                />
              </div>
            </div>
          </div>
          <div className="card">
            <div className="card-body">
              <div className="vstack gap-4">
                <textarea
                  name="cover"
                  value={form.cover}
                  onChange={onChange}
                  className="form-control"
                  rows={1}
                  placeholder={t('coverLinkRequired')}
                />

                <div className="input-group">
                  <input
                    type="file"
                    accept="image/*"
                    className="form-control"
                    name="uploadCover"
                    value={form.uploadCover}
                    onChange={onChange}
                    aria-describedby={t('uploadCover')}
                  />
                  <button
                    disabled={
                      isEdit
                        ? uploadPostCoverMutation.isLoading
                        : uploadPostNewCoverMutation.isLoading
                    }
                    onClick={onClickUploadCover}
                    className="btn btn-outline-secondary"
                    type="button"
                  >
                    {(isEdit
                      ? uploadPostCoverMutation.isLoading
                      : uploadPostNewCoverMutation.isLoading) && (
                      <span
                        className="spinner-border spinner-border-sm me-2"
                        role="status"
                        aria-hidden="true"
                      ></span>
                    )}
                    {t('upload')}
                  </button>
                </div>

                {(form.uploadCoverObjectUrl || form.cover) && (
                  <div className="hstack gap-4">
                    <div
                      style={{ maxWidth: 142, maxHeight: 80 }}
                      className="ratio ratio-16x9"
                    >
                      <img
                        src={
                          form.uploadCoverObjectUrl
                            ? form.uploadCoverObjectUrl
                            : getCover(form.cover, metadata)
                        }
                        alt={t('coverPreview')}
                        title={t('coverRatioSuggestion')}
                        className="object-fit-contain"
                      />
                    </div>
                    <div
                      style={{
                        maxWidth: 260,
                        maxHeight: 146,
                      }}
                      className="ratio ratio-16x9"
                    >
                      <img
                        src={
                          form.uploadCoverObjectUrl
                            ? form.uploadCoverObjectUrl
                            : getCover(form.cover, metadata)
                        }
                        alt={t('coverPreview')}
                        title={t('coverRatioSuggestion')}
                        className="object-fit-contain"
                      />
                    </div>
                    <div
                      style={{
                        maxWidth: 378,
                        maxHeight: 213,
                      }}
                      className="ratio ratio-16x9"
                    >
                      <img
                        src={
                          form.uploadCoverObjectUrl
                            ? form.uploadCoverObjectUrl
                            : getCover(form.cover, metadata)
                        }
                        alt={t('coverPreview')}
                        title={t('coverRatioSuggestion')}
                        className="object-fit-contain"
                      />
                    </div>
                  </div>
                )}
              </div>
            </div>
          </div>
        </form>
      </div>
    </div>
  );
}
